package ExternalService 
{
	import flash.display.Sprite;
	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.filesystem.File;
	import flash.net.FileReference;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLVariables;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.IOErrorEvent;
	import flash.utils.Dictionary;
	
	/**
	 * ...
	 * @author Simon Claeye
	 */
	public class ApiConnection
	{
		private var urlLoader:URLLoader;
		private const baseURL:String = "http://web-geologise.rhcloud.com/api"
		private var tokenKey:String;
		private var username:String;
		
		public function ApiConnection() 
		{
		}
		
		/**
		 * Function to retrieve all of the excursions of which a user is a member
		 * @param	completeHandler the callback function to be invoked upon request completion
		 * @param	statusHandler the callback function to be invoked upon a status event
		 * @param	securityErrorHandler the callback function to be invoked upon a security error
		 * @param	ioErrorHandler the callback function to be invoked in the event of an IO error
		 * @param	contentType the content type header to be used.
		 */
		public function getExcursions(completeHandler:Function, statusHandler:Function,
			securityErrorHandler:Function, ioErrorHandler:Function, contentType:String="application/json"):void
		{	
			urlLoader = new URLLoader();
			var url:String = baseURL+"/excursion/";

			var request:URLRequest = new URLRequest(url);
			request.requestHeaders.push(new URLRequestHeader("Authorization", "Token "+tokenKey));
			request.requestHeaders.push(new URLRequestHeader("Content-type", contentType));
			
			//Variables
			var requestVars:URLVariables = new URLVariables();
			requestVars.format = "json";
			
			request.data = requestVars;
			
			request.method = URLRequestMethod.GET;
			urlLoader.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
			urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler, false, 0, true);
			urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler, false, 0, true);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
			
			urlLoader.load(request);
		}
		
		/**
		 * Function to upload an image to the website.
		 * @param	file the image file to be uploaded.
		 * @param	notes the notes associated with the image file
		 * @param	altitude the altitude
		 * @param	longitude the longitude 
		 * @param	latitude the latitude
		 * @param	heading the heading
		 * @param	hAccuracy the horizontal gps accuracy
		 * @param	vAccuracy the vertical gps accuracy
		 * @param	progressHandler the callback function to be invoked in the case of a progress event
		 * @param	completeHandler the callback function to be invoked upon request completion
		 * @param	statusHandler the callback function to be invoked upon a status event
		 * @param	securityErrorHandler the callback function to be invoked upon a security error
		 * @param	ioErrorHandler the callback function to be invoked in the event of an IO error
		 */
		public function uploadImage(file:File, exursion_id:int, outcrop_id:int, tags:String, notes:String, altitude:Number, longitude:Number, latitude:Number, heading:Number, 
		hAccuracy:Number, vAccuracy:Number, progressHandler:Function, completeHandler:Function,
		statusHandler:Function, securityErrorHandler:Function, ioErrorHandler:Function):void
		{
			urlLoader = new URLLoader();
			var url:String = baseURL+"/image/upload/";

			var request:URLRequest = new URLRequest(url);
			request.requestHeaders.push(new URLRequestHeader("Authorization", "Token "+tokenKey));
			request.requestHeaders.push(new URLRequestHeader("enctype", "multipart/form-data"));
			
			if (notes == null || notes=="")
				notes = " ";
			var geoData:int = 1;
			if (longitude == -1000)
				geoData = 0;
			if (tags == "")
				tags = " "
			
			//Variables
			var requestVars:URLVariables = new URLVariables();
			requestVars.excursion_id =  exursion_id;
			requestVars.outcrop_id = outcrop_id;
			requestVars.name =  file.name;
			requestVars.notes = notes;
			requestVars.geoData = geoData;
			if (geoData == 1)
			{
				requestVars.altitude = altitude;
				requestVars.longitude = longitude;
				requestVars.latitude = latitude;
				requestVars.heading = heading;
				requestVars.hAccuracy = hAccuracy;
				requestVars.vAccuracy = vAccuracy;
			}
			requestVars.tags = tags;
			
			request.data = requestVars;
			request.method = URLRequestMethod.POST;
			
			file.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
			file.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler, false, 0, true);
			file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler, false, 0, true);
			file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
			file.addEventListener(ProgressEvent.PROGRESS, progressHandler, false, 0, true);
			file.upload(request, "image");
		}
		
		/**
		 * Function to obtain an authentication token from the server using the users log in details.
		 * @param	username the user's username
		 * @param	password the user's password
		 * @param	loaderCompleteHandler the callback function to be invoked upon request completion
		 * @param	statusHandler the callback function to be invoked upon a status event
		 * @param	securityErrorHandler the callback function to be invoked upon a security error
		 * @param	ioErrorHandler the callback function to be invoked in the event of an IO error
		 */
		public function getAuthenticationToken(username:String, password:String, loaderCompleteHandler:Function,
		statusHandler:Function, securityErrorHandler:Function, ioErrorHandler:Function):void
		{
			urlLoader = new URLLoader();
			var url:String = baseURL + "/api-token-auth/";
			var request:URLRequest = new URLRequest(url);
			
			//Variables
			var requestVars:URLVariables = new URLVariables()
			requestVars.username = username;
			requestVars.password = password;
			
			request.data = requestVars;
			
			request.method = URLRequestMethod.POST;
			urlLoader.addEventListener(Event.COMPLETE, loaderCompleteHandler, false, 0, true);
			urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler, false, 0, true);
			urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler, false, 0, true);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
			
			urlLoader.load(request);
		}
		
		/**
		 * Function to obtain the outcrop data for a particular excursion
		 * @param	excursionID the primary key of the excursion for which outcrop data should be retrieved
		 * @param	loaderCompleteHandler the callback function to be invoked upon request completion
		 * @param	statusHandler the callback function to be invoked upon a status event
		 * @param	securityErrorHandler the callback function to be invoked upon a security error
		 * @param	ioErrorHandler the callback function to be invoked in the event of an IO error
		 * @param	contentType the content type header to be used.
		 */
		public function getOutcrop(excursionID:int, loaderCompleteHandler:Function,
		statusHandler:Function, securityErrorHandler:Function, ioErrorHandler:Function, contentType:String="application/json"):void
		{
			urlLoader = new URLLoader();
			var url:String = baseURL + "/outcrop/";
			var request:URLRequest = new URLRequest(url);
			request.requestHeaders.push(new URLRequestHeader("Authorization", "Token "+tokenKey));
			request.requestHeaders.push(new URLRequestHeader("Content-type", contentType));
			
			//Variables
			var requestVars:URLVariables = new URLVariables()
			requestVars.ex_id = excursionID;
			requestVars.format = "json";
			
			request.data = requestVars;
			
			request.method = URLRequestMethod.GET;
			urlLoader.addEventListener(Event.COMPLETE, loaderCompleteHandler, false, 0, true);
			urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler, false, 0, true);
			urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler, false, 0, true);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
			
			urlLoader.load(request);
		}
		
		/**
		 * Set the authentication token to be used for authenticating the user.
		 * @param	tokenKey the key to be used
		 */
		public function setToken(tokenKey:String):void
		{
			this.tokenKey = tokenKey;
		}
	}
}